package com.gitee.zw.irmp.common.auth.oauth2;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gitee.zw.irmp.common.auth.oauth2.welink.OAuth2Configuration;
import com.gitee.zw.irmp.common.auth.session.UserSessionStore;
import com.gitee.zw.irmp.common.exception.AuthenticationException;
import com.gitee.zw.irmp.common.auth.IUserService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Slf4j
public abstract class LoginBaseProcessor {

    protected static final ParameterizedTypeReference<Map<String, Object>> STRING_OBJECT_MAP = new ParameterizedTypeReference<Map<String, Object>>() {};

    @Autowired
    protected OAuth2Configuration configuration;
    @Autowired
    protected IUserService userService;
    @Autowired
    protected UserSessionStore userSessionStore;
    @Autowired
    protected ObjectMapper objectMapper;


    protected RestTemplate restTemplate = new RestTemplate();
    protected ResponseEntity<Map<String, Object>> getResponse(RequestEntity<?> request) {
        ResponseEntity<Map<String, Object>> response = null;
        try {
            response = restTemplate.exchange(request, STRING_OBJECT_MAP);
        } catch (Exception ex) {
            String oauth2Error = "An error occurred while attempting to retrieve the UserInfo Resource: " + ex.getMessage();
            throw new AuthenticationException(oauth2Error);
        }
        return response;
    }

    protected Map<String, Object> getUserInfo(HttpServletRequest userRequest, String token) {
        String userNameAttributeName = configuration.getUserNameAttribute();
        if (StringUtils.isEmpty(userNameAttributeName)) {
            String oauth2Error = "Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: "
                    + configuration.getProvider();
            throw new AuthenticationException(oauth2Error);
        }
        RequestEntity<?> request = getUserIdRequest(token, userRequest.getParameter("code"));
        ResponseEntity<Map<String, Object>> response = getResponse(request);
        Map<String, Object> userAttributes = response.getBody();
        log.info("userAttributes: {}", userAttributes);
        return userAttributes;
    }

    protected abstract RequestEntity<?> getUserIdRequest(String token, String code);
    protected void setAuthToken(HttpHeaders headers, String token) {
        headers.setBearerAuth(token);
    }

}
